/**
 * img lazy load plugin
 */
+function (root) {
    'use strict';

    root.lmmf = root.lmmf || {};

    var imgLazy = {};

    var callback = function () {
    };

    var offset, poll, delay, useDebounce;

    var isHidden = function (element) {
        return ($(element).is(':hidden'));
    };

    var inView = function (element, view) {
        if (isHidden(element)) {
            return false;
        }

        var box = element.getBoundingClientRect();
        return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
    };

    var debounceOrThrottle = function () {
        if (!useDebounce && !!poll) {
            return;
        }
        clearTimeout(poll);
        poll = setTimeout(function () {
            imgLazy.render();
            poll = null;
        }, delay);
    };

    imgLazy.init = function (opts) {
        opts = opts || {};
        var offsetAll = opts.offset || 0;
        var offsetVertical = opts.offsetVertical || offsetAll;
        var offsetHorizontal = opts.offsetHorizontal || offsetAll;

        var optionToInt = function (opt, fallback) {
            return parseInt(opt || fallback, 10);
        };
        offset = {
            t: optionToInt(opts.offsetTop, offsetVertical),
            b: optionToInt(opts.offsetBottom, offsetVertical),
            l: optionToInt(opts.offsetLeft, offsetHorizontal),
            r: optionToInt(opts.offsetRight, offsetHorizontal)
        };
        delay = optionToInt(opts.throttle, 250);
        useDebounce = opts.debounce !== false;
        callback = opts.callback || callback;

        imgLazy.render();
        $(window).on('scroll', debounceOrThrottle);
    };

    imgLazy.render = function () {
        var nodes = $('[data-src]');
        var length = nodes.length;
        var view = {
            l: 0 - offset.l,
            t: 0 - offset.t,
            b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,
            r: (root.innerWidth || document.documentElement.clientWidth) + offset.r
        };
        nodes.each(function (i, elem) {
            if (inView(elem, view)) {
                var $elem = $(elem);
                var url = $elem.data('src');
                var img = new Image();
                img.onload = function () {
                    $elem.css({'opacity': 0}).animate({'opacity': 1}, 200).attr('src', url).removeAttr('data-src');
                };
                img.src = url;
                callback(elem, 'load');
            }
        });
        if (!length) {
            imgLazy.detach();
        }
    };

    imgLazy.detach = function () {
        $(window).off('scroll', debounceOrThrottle);
        clearTimeout(poll);
    };

    root.lmmf.imgLazy = imgLazy;

}(window);